package com.car.loan.project.xr.service.loan.payment.impl;

import com.car.loan.common.exception.loan.LoanParameterException;
import com.car.loan.common.utils.BeanUtils;
import com.car.loan.common.utils.SecurityUtils;
import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.project.cm.domain.CmBank;
import com.car.loan.project.cm.domain.CmDealer;
import com.car.loan.project.system.domain.SysDept;
import com.car.loan.project.system.domain.SysUser;
import com.car.loan.project.xr.domain.Customer;
import com.car.loan.project.xr.domain.Loan;
import com.car.loan.project.xr.domain.LoanCar;
import com.car.loan.project.xr.domain.LoanDetail;
import com.car.loan.project.xr.domain.LoanExt;
import com.car.loan.project.xr.domain.LoanStatus;
import com.car.loan.project.xr.mapper.CustomerMapper;
import com.car.loan.project.xr.mapper.LoanCarMapper;
import com.car.loan.project.xr.mapper.LoanDetailMapper;
import com.car.loan.project.xr.mapper.LoanExtMapper;
import com.car.loan.project.xr.mapper.LoanMapper;
import com.car.loan.project.xr.mapper.LoanStatusMapper;
import com.car.loan.project.xr.service.loan.payment.LoanPaymentService;
import com.car.loan.project.xr.util.RedisDataUtil;
import com.car.loan.project.xr.util.bo.business.payment.LoanPaymentApplyBo;
import com.car.loan.project.xr.util.bo.business.payment.PaymentInfoBo;
import com.car.loan.project.xr.util.bo.business.payment.SettleAccountsBo;
import com.car.loan.project.xr.util.enums.BusinessApostilleStatus;
import com.car.loan.project.xr.util.enums.CustomerMarry;
import com.car.loan.project.xr.util.enums.LoanBusinessAuditStatus;
import com.car.loan.project.xr.util.enums.PaymentApplyStatus;
import com.car.loan.project.xr.util.enums.PaymentAuditStatus;
import com.car.loan.project.xr.util.enums.PaymentInfoStatus;
import com.car.loan.project.xr.util.enums.PaymentSettleAccountsStatus;
import com.car.loan.project.xr.util.vo.PaymentApplyVo;
import io.swagger.annotations.ApiModelProperty;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author huangding
 * @description
 * @date 2019/11/26 17:07
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class LoanPaymentServiceImpl implements LoanPaymentService {


    @Autowired
    private RedisDataUtil redisDataUtil;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private LoanMapper loanMapper;

    @Autowired
    private LoanDetailMapper loanDetailMapper;

    @Autowired
    private LoanCarMapper loanCarMapper;

    @Autowired
    private LoanExtMapper loanExtMapper;

    @Autowired
    private LoanStatusMapper loanStatusMapper;

    @Override
    public AjaxResult apply(LoanPaymentApplyBo loanPaymentApplyBo) {
        long loanId = Long.parseLong(loanPaymentApplyBo.getLoanId());
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper
            .selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        if (PaymentApplyStatus.INIT.status != loanStatus.getPaymentApplyStatus()) {
            return AjaxResult.error("当前状态不可提交");
        }
        Long businessAuditStatus = loanStatus.getBusinessAuditStatus();
        Long businessApostilleStatus = loanStatus.getBusinessApostilleStatus();

        if (businessAuditStatus == LoanBusinessAuditStatus.PASS.status
            || businessApostilleStatus == BusinessApostilleStatus.PASS.status) {
            loanStatus.setPaymentApplyStatus(loanPaymentApplyBo.getOperatorStatus());
            loanStatus.setPaymentApplyId(SecurityUtils.getLoginUserId());
            loanStatus.setPaymentApplyTime(LocalDateTime.now());
            loanStatus.setPaymentAuditStatus((long) PaymentAuditStatus.INIT.status);
            loanStatusMapper.updateById(loanStatus);

            Optional<LoanDetail> optionalLoanDetail = loanDetailMapper
                .selectByLoanId(loanId);
            LoanDetail loanDetail = optionalLoanDetail
                .orElseThrow(() -> new LoanParameterException("业务数据详情信息异常"));

            loanDetail.setPurchaseTax(loanPaymentApplyBo.getPurchaseTax());
            loanDetail.setInsurance(loanPaymentApplyBo.getInsurance());
            loanDetail.setEvaluation(loanPaymentApplyBo.getEvaluation());
            loanDetail.setGps(loanPaymentApplyBo.getGps());
            loanDetail.setGuarantee(loanPaymentApplyBo.getGuarantee());
            loanDetail.setBond(loanPaymentApplyBo.getBond());
            loanDetail.setOther(loanPaymentApplyBo.getOther());
            loanDetail.setBankAccountName(loanPaymentApplyBo.getBankAccountName());
            loanDetail.setBankName(loanPaymentApplyBo.getBankName());
            loanDetail.setBankAccountNo(loanPaymentApplyBo.getBankAccountNo());
            loanDetail.setSettleRate(loanPaymentApplyBo.getSettleRate());
            loanDetail.setDiscountRate(loanPaymentApplyBo.getDiscountRate());
            loanDetail.setSalesmanBankAccountName(loanPaymentApplyBo.getSalesmanBankAccountName());
            loanDetail.setSalesmanBankAccountNo(loanPaymentApplyBo.getSalesmanBankAccountNo());
            loanDetail.setSalesmanBankName(loanPaymentApplyBo.getSalesmanBankName());
            loanDetail.setShouldAmount(loanPaymentApplyBo.getShouldAmount());
            loanDetailMapper.updateById(loanDetail);
            return AjaxResult.success();
        } else {
            return AjaxResult.error("请先通过业务审核");
        }


    }

    @Override
    public AjaxResult info(long loanId) {

        PaymentApplyVo paymentApplyVo = new PaymentApplyVo();
        Optional<Loan> optionalLoan
            = Optional.ofNullable(loanMapper.selectById(loanId));
        Loan loan = optionalLoan.orElseThrow(() -> new LoanParameterException("无该业务数据"));
        //获取页面展示信息
        paymentApplyVo.setAdminName(redisDataUtil.getAdminName(loan.getAdminId()));
        paymentApplyVo.setAdminId(loan.getAdminId());
        paymentApplyVo.setDealerId(loan.getDealerId());
        paymentApplyVo.setBusinessNo(loan.getBusinessNo());
        paymentApplyVo.setBankName(redisDataUtil.getBankName(loan.getBankId()));
        paymentApplyVo.setDealerName(
            redisDataUtil.getDealerName(loan.getDealerId()));
        paymentApplyVo.setDeptName(
            redisDataUtil.getDeptName(loan.getDeptId()));

//        //获取数据源
        Optional<LoanExt> optionalLoanExt = loanExtMapper.selectByLoanId(loanId);
        LoanExt loanExt = optionalLoanExt
            .orElseThrow(() -> new LoanParameterException("业务数据扩展信息异常"));

        Optional<LoanDetail> optionalLoanDetail = loanDetailMapper.selectByLoanId(loanId);
        LoanDetail loanDetail = optionalLoanDetail
            .orElseThrow(() -> new LoanParameterException("业务数据详情信息异常"));

        Optional<LoanCar> optionalLoanCar = loanCarMapper.selectByLoanId(loanId);
        LoanCar loanCar = optionalLoanCar
            .orElseThrow(() -> new LoanParameterException("业务数据车辆信息异常"));

        //客户信息
        Customer customer = customerMapper.selectById(loan.getCustomerId());
        paymentApplyVo.setCustomerName(customer.getName());
        paymentApplyVo.setMobile(customer.getMobile());
        paymentApplyVo.setIdCardNo(customer.getIdCardNo());
        //车辆信息
        paymentApplyVo.setCarName(loanExt.getCarName());
        paymentApplyVo.setCarType(loanCar.getCarType());
        paymentApplyVo.setCarNature(loanCar.getCarNature());
        paymentApplyVo.setPlateType(loanCar.getPlateType());
        paymentApplyVo.setRegistCity(loanCar.getRegistCity());
        paymentApplyVo.setRegistProvince(loanCar.getRegistProvince());

        //金额信息
        paymentApplyVo.setSellAmount(loanExt.getSellAmount());
        paymentApplyVo.setInstallmentAmount(loanExt.getInstallmentAmount());
        paymentApplyVo.setRate(loanExt.getRate());
        paymentApplyVo.setBankRate(loanExt.getBankRate());
        paymentApplyVo.setFinancingAmount(loanExt.getFinancingAmount());
        paymentApplyVo.setTerm(loanExt.getTerm());
        paymentApplyVo.setMissingRemark(loanDetail.getMissingRemark());
        paymentApplyVo.setBusinessSuggest(loanDetail.getBusinessSuggest());

        //添加录入字段信息
        LoanPaymentApplyBo loanPaymentApplyBo = new LoanPaymentApplyBo();
        BeanUtils.copyBeanProp(loanPaymentApplyBo, loanDetail);
        loanPaymentApplyBo.setLoanId(String.valueOf(loanDetail.getLoanId()));
        loanPaymentApplyBo.setShouldAmount(loanDetail.getShouldAmount());
        paymentApplyVo.setLoanPaymentApply(loanPaymentApplyBo);

        //付款信息填写字段
        PaymentInfoBo paymentInfoBo = new PaymentInfoBo();
        paymentInfoBo.setLoanId(String.valueOf(loanId));
        paymentInfoBo.setAdvanceDate(loanDetail.getAdvanceDate());
        paymentInfoBo.setAdvanceAmount(loanDetail.getAdvanceAmount());
        paymentInfoBo.setAdvanceRemark(loanDetail.getAdvanceRemark());
        paymentApplyVo.setPaymentInfo(paymentInfoBo);

        //结清信息填写字段
        SettleAccountsBo settleAccountsBo = new SettleAccountsBo();
        settleAccountsBo.setLoanId(String.valueOf(loanId));
        settleAccountsBo.setSalesmanFinedAmount(loanDetail.getSalesmanFinedAmount());
        settleAccountsBo.setSettleDate(loanDetail.getSalesmanRebateDate());
        settleAccountsBo.setSettleAmount(loanDetail.getSalesmanRebateAmount());
        settleAccountsBo.setRemark(loanDetail.getSalesmanRemark());
        settleAccountsBo.setSettleRemark(loanExt.getSettleRemark());
        paymentApplyVo.setSettleAccounts(settleAccountsBo);

        return AjaxResult.success(paymentApplyVo);
    }


    @Override
    public AjaxResult audit(Long loanId, Long operatorStatus) {
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper
            .selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        if (PaymentAuditStatus.INIT.status != loanStatus.getPaymentAuditStatus()) {
            return AjaxResult.error("当前状态不可提交");
        }
        loanStatus.setPaymentAuditStatus(operatorStatus);
        loanStatus.setPaymentAuditId(SecurityUtils.getLoginUserId());
        loanStatus.setPaymentAuditTime(LocalDateTime.now());
        loanStatusMapper.updateById(loanStatus);
        return AjaxResult.success();
    }


    @Override
    public AjaxResult paymentInfoWrite(PaymentInfoBo paymentInfoBo) {
        long loanId = Long.parseLong(paymentInfoBo.getLoanId());
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper
            .selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        if (PaymentInfoStatus.INIT.status != loanStatus.getPaymentInfoStatus()) {
            return AjaxResult.error("当前状态不可提交");
        }
        loanStatus.setPaymentInfoStatus(paymentInfoBo.getOperatorStatus());
        loanStatus.setPaymentInfoId(SecurityUtils.getLoginUserId());
        loanStatus.setPaymentInfoTime(LocalDateTime.now());
        loanStatus.setSettleAccountsStatus((long) PaymentSettleAccountsStatus.INIT.status);
        loanStatusMapper.updateById(loanStatus);

        Optional<LoanDetail> optionalLoanDetail = loanDetailMapper
            .selectByLoanId(loanId);
        LoanDetail loanDetail = optionalLoanDetail
            .orElseThrow(() -> new LoanParameterException("业务数据详情信息异常"));
        loanDetail.setAdvanceRemark(paymentInfoBo.getAdvanceRemark());
        loanDetail.setAdvanceAmount(paymentInfoBo.getAdvanceAmount());
        loanDetail.setAdvanceDate(paymentInfoBo.getAdvanceDate());
        loanDetailMapper.updateById(loanDetail);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult settleAccountsInfoWrite(SettleAccountsBo settleAccountsBo) {
        long loanId = Long.parseLong(settleAccountsBo.getLoanId());
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper
            .selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        if (PaymentSettleAccountsStatus.INIT.status != loanStatus.getSettleAccountsStatus()) {
            return AjaxResult.error("当前状态不可提交");
        }
        loanStatus.setSettleAccountsStatus(settleAccountsBo.getOperatorStatus());
        loanStatus.setSettleAccountsId(SecurityUtils.getLoginUserId());
        loanStatus.setSettleAccountsTime(LocalDateTime.now());
        loanStatusMapper.updateById(loanStatus);

        Optional<LoanDetail> optionalLoanDetail = loanDetailMapper
            .selectByLoanId(loanId);
        LoanDetail loanDetail = optionalLoanDetail
            .orElseThrow(() -> new LoanParameterException("业务数据详情信息异常"));
        loanDetail.setSalesmanFinedAmount(settleAccountsBo.getSalesmanFinedAmount());
        loanDetail.setSalesmanRebateDate(settleAccountsBo.getSettleDate());
        loanDetail.setSalesmanRebateAmount(settleAccountsBo.getSettleAmount());
        loanDetail.setSalesmanRemark(settleAccountsBo.getRemark());

        loanDetailMapper.updateById(loanDetail);

        Optional<LoanExt> optionalLoanExt = loanExtMapper.selectByLoanId(loanId);
        LoanExt loanExt = optionalLoanExt
            .orElseThrow(() -> new LoanParameterException("业务数据扩展信息异常"));
        loanExt.setSettleRemark(settleAccountsBo.getSettleRemark());
        loanExtMapper.updateById(loanExt);
        return AjaxResult.success();
    }
}
